package com.ruoyi.common.utils.equipment;

import java.util.Arrays;
import java.util.Random;

//通讯命令帧类
public class C502Mframe
{

	private static int MAX_DATA_COUNT = 340; //数据命令最大值
	private byte mFrame[];//完整命令数组
	private int mAddr;//机器号
	private int mCode;//信息代码
	private int mCmdType ;//命令类型
	private int mCmdPar;//命令参数
	private int mDataLen;//数据长度
	private byte mCmdData[]; //命令数据
	private int mCheckData ; //检验和

	C502Mframe(){};

	C502Mframe(int iAddr,int iCmdType,int iCmdPar){
		int iCode;
		iCode = GetRndNum();//获取一个随机数
		CreateFrame(iAddr,iCode,iCmdType,iCmdPar,0,null);
	}

	C502Mframe(int iAddr,int iCmdType,int iCmdPar,int iDataLen,byte [] Databuf){
		int iCode;
		iCode = GetRndNum();//获取一个随机数
		CreateFrame(iAddr,iCode,iCmdType,iCmdPar,iDataLen,Databuf);
	}
	C502Mframe(int iAddr,int iCode,int iCmdType,int iCmdPar,int iDataLen,byte [] Databuf){
		CreateFrame(iAddr,iCode,iCmdType,iCmdPar,iDataLen,Databuf);
	}
	public void CreateFrame(int iAddr,int iCode,int iCmdType,int iCmdPar,int iDataLen,byte [] Databuf){
		SetAddr(iAddr);
		SetCode(iCode);
		SetCmdType(iCmdType);
		SetCmdPar(iCmdPar);
		SetDataLen(iDataLen);
		if (iDataLen>0 && (Databuf != null)){
			SetDatabuff(Databuf);
		}
		//开始生成命令帧
		Create();
	}


	//机器号
	public void SetAddr(int iAddr){mAddr = iAddr & 0xff;}
	public int GetAddr(){return mAddr;}


	//信息代码
	public void SetCode(int lData){mCode = lData & 0xffff;}
	public int GetCode(){return mCode;}

	//命令类型
	public void SetCmdType(int iData){mCmdType = iData & 0xff;}
	public int GetCmdType(){return mCmdType;}

	//命令参数
	public void SetCmdPar(int iData){mCmdPar = iData & 0xff;}
	public int GetCmdPar(){return mCmdPar;}

	//数据长度
	public void SetDataLen(int iData){mDataLen = iData & 0xff;}
	public int GetDataLen(){return mDataLen;}

	//命令数据
	public void SetDatabuff(byte[] iData){mCmdData = Arrays.copyOf(iData,iData.length);}
	public byte[] GetDatabuff(){return Arrays.copyOf(mCmdData,mCmdData.length);}

	//返回检验和
	public int GetCheckData(){return mCheckData;}

	//设置命令数据长度
	public void SetDatabuffSize(int size){mCmdData = new byte[size];}

	//设置命令数据内容
	public void SetDataValue(int lIndex,byte bValue){mCmdData[lIndex]=bValue;}

	//设置命令数据内容
	public void SetDataValue(int lIndex,byte[] bValue)
	{
		for(int i=0;i<bValue.length;i++)
			mCmdData[lIndex+i]=bValue[i];
	}
	//返回原始数据包
	public byte[] GetFrame(){return Arrays.copyOf(mFrame,mFrame.length);}

	//返回一个取值范围在0xfe-0x10 之间的数值
	private int GetRndNum()
	{
		Random random = new Random(System.currentTimeMillis());
		long ivalue = (long)(random.nextDouble() * 254);
		return (int)(ivalue+16);
	}


	//创建数据包，并计算校验和
	public boolean Create()
	{
		byte buf[];
		int iBufLen=0,iBegin=0;
		int i;
		//计算数据包长度
		iBufLen = 1 //机器号
				+ 2 //信息代码
				+ 1 //分类
				+ 1 //参数
				+ 1 //数据长度
				+ mDataLen //数据内容
				+ 1 //检验和
				+ 2;//标志
		//创建缓冲
		buf=new byte[iBufLen];
		//先设置起始和结束标识
		buf[0]=126;//7E
		buf[iBufLen-1]=126;//7E

		//机器号
		buf[1] = (byte)(mAddr);

		//填充信息代码
		mCode = mCode & 0xffff;
		buf[2]=(byte)(mCode>>8);
		buf[3]=(byte)(mCode & 0xff);

		//命令类型
		buf[4]=(byte)(mCmdType);
		//命令参数
		buf[5]=(byte)(mCmdPar);

		//数据长度
		buf[6]=(byte)(mDataLen);
		//命令数据
		iBegin=7;
		if(mDataLen>0 && (mCmdData != null) ){
			for(i=0;i<mDataLen;i++){
				buf[iBegin++]=mCmdData[i];
				//计算检验和


			}
			long lCheck;
			lCheck=0;
			for(i=1;i<iBufLen-2;i++){
				lCheck+=ConverterTool.uByte(buf[i]);//取字节的无符号整形数值
			}
			//检验和
			mCheckData=(byte)(lCheck % 256);
			buf[iBegin]=(byte)mCheckData;

		}
		//进行转译码处理并保存数据
		mFrame = TranslateCommandFrame(buf);
		return true;
	}

	private byte[] TranslateCommandFrame(byte[] buf)
	{//对命令中的需要转译的数据进行处理 7E = 7F 01; 7F=7F 02;
		byte [] iData;
		int iIndex=1,i,iValue;
		//开始命令转译
		iData = new byte[buf.length*2];
		iData[0] = buf[0];

		for(i = 1 ;i<buf.length-1;i++)
		{
			iValue=ConverterTool.uByte(buf[i]);//取字节的无符号整形数值
			switch (iValue)
			{
				case 126://7E = 7F 01
					iData[iIndex++] = (byte)127;
					iData[iIndex++] = 1;
					break;
				case 127://7F = 7F 02
					iData[iIndex++] = (byte)127;
					iData[iIndex++] = 2;
					break;
				default:
					iData[iIndex++] = buf[i];
			}
		}
		iData[iIndex++] = buf[i];
		return Arrays.copyOf(iData,iIndex);
	}


}
